package de.uni_mannheim.informatik.ai.dame_ai.dame.application;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Move;
import de.uni_mannheim.informatik.ai.dame_ai.main.application.GameSettings;
import de.uni_mannheim.informatik.ai.dame_ai.util.FileSystem;
import de.uni_mannheim.informatik.ai.dame_ai.util.GameSettingsParser;
import de.uni_mannheim.informatik.ai.dame_ai.util.InvalidStateException;
import de.uni_mannheim.informatik.ai.dame_ai.util.InvalidXmlException;
import de.uni_mannheim.informatik.ai.dame_ai.util.XmlCompiler;
import de.uni_mannheim.informatik.ai.dame_ai.util.XmlElement;
import de.uni_mannheim.informatik.ai.dame_ai.util.XmlFileAccess;
import de.uni_mannheim.informatik.ai.dame_ai.util.XmlParser;


public class DamePersistor {
	private XmlCompiler compiler = new XmlCompiler();
	private XmlParser parser= new XmlParser();
	private XmlFileAccess fileAccess=new XmlFileAccess();
	private GameSettingsParser gameSettingsParser = new GameSettingsParser();
	private File autosave = FileSystem.getAutoSave(FileSystem.GameName.dame);
	public String compileXml(XmlElement element){
		return compiler.compile(element);
	}
	public boolean persist(GameSettings data,ArrayList<Move> moves, File dest){
		XmlElement stateTree= buildTree(moves, data);
		String xmlRep = compiler.compile(stateTree);
		boolean sucessful= fileAccess.writeXml(xmlRep, dest);
		return sucessful;
	}
	public boolean autoSave(GameSettings data, ArrayList<Move> moves){
		XmlElement stateTree= buildTree(moves, data);
		String xmlRep = compiler.compile(stateTree);
		boolean sucessful= fileAccess.writeXml(xmlRep, autosave);
		return sucessful;
	}
	public XmlElement buildTree(ArrayList<Move> moves, GameSettings data){
		XmlElement root = new XmlElement("state");
		root.addChild(gameSettingsParser.setGameSettings(data));
		for(Move move : moves){
			root.addChild(getState(move));
		}
		return root;
	}
	public GameSettings getGameSettings(XmlElement root){
		return gameSettingsParser.getGameSettings(root);

	}
	public XmlElement getRoot(File destFile){
		String xmlFile = fileAccess.readFile(destFile);
		XmlElement root = null;
		try {
			root = parser.parse(xmlFile);
		} catch (InvalidXmlException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return root;
		
	}
	public ArrayList<Move> getMoves(XmlElement root){
		ArrayList<Move> moves = new ArrayList<Move>();
		Collection<XmlElement> elements =root.getChildren();
		for(XmlElement element : elements){
			if(element.getTagName().equals("move")){
				try {
					moves.add(setState(element));
				} catch (InvalidStateException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return moves;
	}
	public Move setState(XmlElement moveElement) throws InvalidStateException{
		if(!(moveElement.getTagName().startsWith("move")))
			throw new InvalidStateException("The XmlElemnt passed to" +
							"setState(MillBoard board, XmlElement state) is not a valid state!");
		XmlElement selectedPosition = moveElement.getChild("selectedPosition");
		XmlElement target = moveElement.getChild("target");
		XmlElement isJump = moveElement.getChild("isJump");
		int intSelectedPosition = Integer.parseInt(selectedPosition.getContent());
		int intTarget = Integer.parseInt(target.getContent());
		boolean booleanIsJump = Boolean.parseBoolean(isJump.getContent());
		return new Move(intSelectedPosition,intTarget,booleanIsJump);
	}
	public XmlElement getState(Move move){
		
		XmlElement xmlMove =new XmlElement("move");
		xmlMove.addChild("selectedPosition", ""+move.getFromPos());
		xmlMove.addChild("target",""+move.getToPos());
		xmlMove.addChild("isJump",""+move.isJump());
		return xmlMove;
		
	}
}
